"""
按分类丰富景点数据
从高德地图API获取不同类别的景点数据
"""
from django.core.management.base import BaseCommand
from django.conf import settings
from django.core.cache import cache
from apps.attractions.models import Attraction
from utils.amap_client import AMapClient
from decimal import Decimal
import time


class Command(BaseCommand):
    help = '按分类丰富景点数据'

    def add_arguments(self, parser):
        parser.add_argument(
            '--category',
            type=str,
            choices=['natural', 'modern', 'food', 'all'],
            default='all',
            help='要同步的类别（natural: 自然风光, modern: 现代建筑, food: 美食购物, all: 全部）'
        )
        parser.add_argument(
            '--max-count',
            type=int,
            default=50,
            help='每个类别最大同步数量，默认50'
        )
        parser.add_argument(
            '--location',
            type=str,
            default='115.89,28.68',
            help='中心点坐标，格式：经度,纬度（默认：南昌市中心）'
        )
        parser.add_argument(
            '--radius',
            type=int,
            default=50000,
            help='搜索半径（米），默认50000（50公里）'
        )

    def handle(self, *args, **options):
        # 检查API Key
        api_key = settings.AMAP_CONFIG.get('API_KEY')
        if not api_key or api_key == 'your_amap_api_key':
            self.stdout.write(
                self.style.ERROR('❌ 高德地图API Key未配置！')
            )
            return

        category = options['category']
        max_count = options['max_count']
        location = options['location']
        radius = options['radius']

        self.stdout.write(self.style.SUCCESS('=' * 60))
        self.stdout.write(self.style.SUCCESS('开始按分类丰富景点数据'))
        self.stdout.write(self.style.SUCCESS('=' * 60))
        self.stdout.write(f'类别: {category}')
        self.stdout.write(f'每个类别最大数量: {max_count}')
        self.stdout.write(f'搜索位置: {location}')
        self.stdout.write(f'搜索半径: {radius}米')
        self.stdout.write('')

        amap_client = AMapClient(api_key)

        # 定义各类别的搜索关键词
        category_keywords = {
            'natural': [
                '公园', '风景区', '自然景观', '湖泊', '山', '湿地', '森林公园',
                '生态园', '植物园', '动物园', '水景', '瀑布', '温泉'
            ],
            'modern': [
                '博物馆', '科技馆', '展览馆', '艺术馆', '图书馆', '体育馆',
                '购物中心', '商业街', '广场', '摩天大楼', '地标建筑', '现代建筑'
            ],
            'food': [
                '美食街', '小吃街', '餐厅', '特色小吃', '美食城', '夜市',
                '购物街', '商业街', '特产', '美食广场'
            ]
        }

        categories_to_sync = []
        if category == 'all':
            categories_to_sync = ['natural', 'modern', 'food']
        else:
            categories_to_sync = [category]

        total_added = 0

        for cat in categories_to_sync:
            self.stdout.write(self.style.WARNING(f'\n处理类别: {cat}'))
            keywords = category_keywords.get(cat, [])
            
            added_count = 0
            processed_poi_ids = set()
            
            # 获取已存在的POI ID
            existing_poi_ids = set(
                Attraction.objects.exclude(amap_poi_id__isnull=True)
                .exclude(amap_poi_id='')
                .values_list('amap_poi_id', flat=True)
            )
            
            for keyword in keywords:
                if added_count >= max_count:
                    break
                
                self.stdout.write(f'  搜索关键词: {keyword}')
                
                try:
                    # 搜索POI
                    result = amap_client.search_pois_by_keyword(
                        keyword=keyword,
                        city='南昌',
                        types='风景名胜|餐饮服务|购物服务|科教文化服务',
                        offset=1,
                        page=1,
                        extensions='all'
                    )
                    
                    if not result or 'pois' not in result:
                        self.stdout.write(f'    未找到结果')
                        continue
                    
                    pois = result['pois']
                    self.stdout.write(f'    找到 {len(pois)} 个POI')
                    
                    for poi in pois[:max_count - added_count]:
                        poi_id = poi.get('id')
                        if not poi_id or poi_id in processed_poi_ids or poi_id in existing_poi_ids:
                            continue
                        
                        processed_poi_ids.add(poi_id)
                        
                        # 获取POI详情
                        try:
                            poi_detail = amap_client.get_poi_detail(poi_id)
                            if not poi_detail:
                                continue
                            
                            # 解析数据
                            name = poi_detail.get('name', '').strip()
                            if not name:
                                continue
                            
                            # 检查是否已存在同名景点
                            if Attraction.objects.filter(name=name).exists():
                                continue
                            
                            location_str = poi_detail.get('location', '')
                            if not location_str:
                                continue
                            
                            lon, lat = location_str.split(',')
                            
                            # 创建景点
                            attraction = Attraction.objects.create(
                                name=name,
                                category=cat,
                                latitude=Decimal(lat),
                                longitude=Decimal(lon),
                                address=poi_detail.get('address', ''),
                                description=poi_detail.get('introduction', '') or poi_detail.get('description', ''),
                                amap_poi_id=poi_id,
                                ticket_price=Decimal('0'),  # 默认免费，后续可更新
                                popularity=0,
                                rating=0
                            )
                            
                            # 获取图片
                            try:
                                photos = poi_detail.get('photos', [])
                                if isinstance(photos, str):
                                    import json
                                    photos = json.loads(photos)
                                
                                if isinstance(photos, list) and len(photos) > 0:
                                    image_urls = []
                                    for photo in photos[:5]:  # 最多5张图片
                                        photo_url = photo.get('url', '') if isinstance(photo, dict) else str(photo)
                                        if photo_url:
                                            if not photo_url.startswith('http'):
                                                photo_url = 'https://restapi.amap.com' + photo_url
                                            image_urls.append(photo_url)
                                    
                                    if image_urls:
                                        attraction.amap_image_urls = image_urls
                                        attraction.save(update_fields=['amap_image_urls'])
                            except Exception as e:
                                self.stdout.write(f'    获取图片失败: {e}')
                            
                            added_count += 1
                            total_added += 1
                            self.stdout.write(
                                self.style.SUCCESS(f'    ✓ 添加: {name}')
                            )
                            
                            # 避免请求过快
                            time.sleep(0.2)
                            
                        except Exception as e:
                            self.stdout.write(
                                self.style.ERROR(f'    处理POI失败: {e}')
                            )
                            continue
                    
                    # 避免请求过快
                    time.sleep(0.5)
                    
                except Exception as e:
                    self.stdout.write(
                        self.style.ERROR(f'  搜索失败: {e}')
                    )
                    continue
            
            self.stdout.write(
                self.style.SUCCESS(f'\n类别 {cat} 共添加 {added_count} 个景点')
            )

        # 清除缓存
        if total_added > 0:
            self.stdout.write(self.style.WARNING('\n清除景点数据缓存...'))
            try:
                if hasattr(cache, 'delete_pattern'):
                    cache.delete_pattern('attractions_list_*')
                    cache.delete_pattern('attraction_detail_*')
                    cache.delete_pattern('attraction_recommendations_*')
                    self.stdout.write(self.style.SUCCESS('✓ 已清除景点相关缓存'))
                else:
                    cache.clear()
                    self.stdout.write(self.style.SUCCESS('✓ 已清除所有缓存'))
            except Exception as e:
                self.stdout.write(self.style.WARNING(f'清除缓存时出错: {e}'))
        
        self.stdout.write(self.style.SUCCESS('\n' + '=' * 60))
        self.stdout.write(self.style.SUCCESS(f'总共添加 {total_added} 个景点'))
        self.stdout.write(self.style.SUCCESS('=' * 60))

